package com.cms.controllers;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.cms.common.hibernate.BaseEntity;
import com.cms.service.MyBaseService;
import com.cms.support.Result;
import com.cms.support.StringEditor;

/**
 * 功能说明：springmvc的基类，处理异常，公共方法
 * 
 * @author ducc
 * @created 2014年6月27日 上午6:19:14
 * @updated
 * @param <T>
 */
public abstract class BaseController<T extends BaseEntity> {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());

	protected abstract String getPrefix();

	protected abstract Class<?> getClazz();

	protected Class<?> clazz = getClazz();

	protected String ADD = getPrefix() + "/add";
	protected String EDIT = getPrefix() + "/modify";
	protected String VIEW = getPrefix() + "/view";
	protected String LIST = getPrefix() + "/list";
	protected String INDEX = getPrefix() + "/index";

	@Autowired
	protected MyBaseService myBaseService;

	/**
	 * 功能说明：通用返回到index
	 * 
	 * @author ducc
	 * @updated
	 * @param request
	 * @param model
	 * @param item
	 * @return
	 */
	@RequestMapping("")
	public String index() {
		return INDEX;
	}

	/**
	 * 功能说明：通用列表查询方法
	 * 
	 * @author ducc
	 * @updated
	 * @param request
	 * @param model
	 * @param item
	 * @return
	 */
	@ResponseBody
	@RequestMapping("list")
	public Object list(Model model, @ModelAttribute T entity,
			Integer iDisplayLength, Integer iDisplayStart, Integer sEcho) {
		try {
			Long totalCount = myBaseService.countByExample(entity);
			List<T> list = myBaseService.listByExample(entity, iDisplayStart,
					iDisplayLength);
			JSONObject getObj = new JSONObject();
			getObj.put("sEcho", sEcho);// 不知道这个值有什么用,有知道的请告知一下
			getObj.put("iTotalRecords", totalCount);// 实际的行数
			getObj.put("iTotalDisplayRecords", totalCount);// 显示的行数,这个要和上面写的一样
			getObj.put("aaData", list);// 要以JSON格式返回
			return getObj;
		} catch (Exception e) {
			logger.error("error:", e);
			return null;
		}
	}

	/**
	 * 功能说明：通用跳转到新增页面
	 * 
	 * @author ducc
	 * @updated
	 * @return
	 */
	@RequestMapping(value = "add", method = RequestMethod.GET)
	protected String add() {
		return ADD;
	}

	/**
	 * 功能说明：通用新增页面
	 * 
	 * @author ducc
	 * @updated
	 * @param response
	 * @param item
	 */
	@ResponseBody
	@RequestMapping(value = "add", method = RequestMethod.POST)
	public Object add(HttpServletResponse response, @ModelAttribute T item) {
		try {
			myBaseService.saveOrUpdate(item);
			return new Result();
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "服务器处理异常");
		}
	}

	/**
	 * 功能说明：通用跳转到编辑页面
	 * 
	 * @author ducc
	 * @updated
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "modify")
	public String edit(Model model, Long id) {
		model.addAttribute("entity", myBaseService.get(clazz, id));
		return EDIT;
	}

	/**
	 * 功能说明：通用修改页面
	 * 
	 * @author ducc
	 * @updated
	 * @param response
	 * @param item
	 */
	@ResponseBody
	@RequestMapping(value = "modify", method = RequestMethod.POST)
	public Object edit(HttpServletResponse response, @ModelAttribute T item) {
		try {
			myBaseService.saveOrUpdate(item);
			return new Result();
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "服务器处理异常");
		}
	}

	@RequestMapping(value = "view")
	public String view(Model model, Long id) {
		model.addAttribute("entity", myBaseService.get(clazz, id));
		return VIEW;
	}

	/**
	 * 功能说明：通用删除功能
	 * 
	 * @author ducc
	 * @updated
	 * @param response
	 *            HttpServletResponse
	 * @param id
	 *            删除的id
	 */
	@ResponseBody
	@RequestMapping(value = "del")
	public Object del(HttpServletResponse response, Long id) {
		try {
			if (id != null) {
				myBaseService.deleteById(clazz, id);
				return new Result();
			} else {
				return new Result(false, "记录不存在");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "服务器处理异常");
		}
	}

	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(
				dateFormat, true));
		binder.registerCustomEditor(String.class, new StringEditor());
	}

	@ExceptionHandler
	public String exception(HttpServletRequest request,
			HttpServletResponse response, Exception e) {
		logger.error(this.getClass() + " is errory, errorType=" + e.getClass(),
				e);
		// 如果是json格式的ajax请求
		if (request.getHeader("accept").indexOf("application/json") > -1
				|| (request.getHeader("X-Requested-With") != null && request
						.getHeader("X-Requested-With")
						.indexOf("XMLHttpRequest") > -1)) {
			response.setStatus(500);
			response.setContentType("application/json;charset=utf-8");
			return null;
		} else {// 如果是普通请求
			request.setAttribute("exceptionMsg", e.getMessage());
			// 根据不同的异常类型可以返回不同界面
			if (e instanceof SQLException)
				return "sqlerror";
			else
				return "error";
		}
	}
}